package demo.ssh2;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Vector;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class SSHCommandExecutor {

    private static final Logger logger = LoggerFactory.getLogger(SSHCommandExecutor.class);

    private String ipAddress;

    private String username;

    private String password;

    public static final int DEFAULT_SSH_PORT = 22;

    private static final String USERHOME = "/" + System.getProperty("user.home") + "/";

    private static final String PRIVATEKEY = ".ssh/id_rsa";

    private static final String PUBLICKEY = "/.ssh/id_rsa.pub";

    private static final String DEFAULT_KNOWNHOSTS = "/.ssh/known_hosts";

    private Vector<String> stdout;

    public SSHCommandExecutor(final String ipAddress, final String username, final String password) {

        this.ipAddress = ipAddress;
        this.username = username;
        this.password = password;
        stdout = new Vector<String>();
    }

    public int execute(final String command) throws Exception {

        int returnCode = 0;
        JSch jsch = new JSch();
        SSHUserInfo userInfo = new SSHUserInfo();

        // try {
        if (logger.isInfoEnabled()) {
            logger.info("ssh connect to server ip:{}, user:{}, password:{}", ipAddress, username, password);
        }
        // Create and connect session.
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        Session session = null;
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            logger.info("get session only by ip:{}", ipAddress);
            jsch.setKnownHosts(USERHOME + DEFAULT_KNOWNHOSTS);
            jsch.addIdentity(USERHOME + PRIVATEKEY);
            session = jsch.getSession(ipAddress);

        } else {
            logger.info("get session by ip,username and password:{},{},{}", ipAddress, username, password);
            session = jsch.getSession(username, ipAddress, DEFAULT_SSH_PORT);
            session.setConfig(config);
            session.setPassword(password);
            session.setUserInfo(userInfo);
        }

        // Create and connect channel.
        Channel channel = session.openChannel("exec");
        ((ChannelExec) channel).setCommand(command);

        channel.connect();
        if (logger.isInfoEnabled()) {
            logger.info("The remote command is: " + command);
        }

        // Disconnect the channel and session.
        channel.disconnect();
        session.disconnect();
        return returnCode;
    }

    public String execute4Response(final String command) throws Exception {

        JSch jsch = new JSch();
        SSHUserInfo userInfo = new SSHUserInfo();

        // try {
        if (logger.isInfoEnabled()) {
            logger.info("ssh connect to server ip:{}, user:{}, password:{}", ipAddress, username, password);
        }
        // Create and connect session.
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        Session session = null;
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            logger.info("get session only by ip:{}", ipAddress);
            jsch.setKnownHosts(USERHOME + DEFAULT_KNOWNHOSTS);
            jsch.addIdentity(USERHOME + PRIVATEKEY);
            session = jsch.getSession(ipAddress);

        } else {
            logger.info("get session by ip,username and password:{},{},{}", ipAddress, username, password);
            session = jsch.getSession(username, ipAddress, DEFAULT_SSH_PORT);
            session.setConfig(config);
            session.setPassword(password);
            session.setUserInfo(userInfo);
        }
        session.connect();

        // Create and connect channel.
        Channel channel = session.openChannel("exec");
        ((ChannelExec) channel).setCommand(command);

        channel.connect();
        if (logger.isInfoEnabled()) {
            logger.info("The remote command is: " + command);
        }

        InputStream inputStream = channel.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("utf-8")));
        StringBuilder stringBuilder = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            if (org.apache.commons.lang.StringUtils.containsIgnoreCase(line,
                    "com.ximalaya.xmen.iceman.instance.StartEngine")) {
                stringBuilder.append(line);
            }
        }

        String res = stringBuilder.toString();
        reader.close();

        // Disconnect the channel and session.
        channel.disconnect();
        session.disconnect();
        return res;
    }

    public Vector<String> getStandardOutput() {

        return stdout;
    }

}
